package com.scs.application.modules.sys.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.query.QueryContextHolder;
import com.scs.application.core.utils.CacheUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.modules.sys.adapter.DataViewAdapter;
import com.scs.application.modules.sys.dto.CreateCRUDFileDTO;
import com.scs.application.modules.sys.dto.CreateFrontFileDTO;
import com.scs.application.modules.sys.dto.DataViewDTO;
import com.scs.application.modules.sys.dto.StringReceive;
import com.scs.application.modules.sys.entity.DataView;
import com.scs.application.modules.sys.entity.Flow;
import com.scs.application.modules.sys.mapper.DataViewMapper;
import com.scs.application.modules.sys.model.PageResult;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.sys.properties.SystemProperties;
import com.scs.application.modules.sys.service.DataViewService;
import com.scs.application.modules.sys.service.ProgramService;
import com.scs.application.modules.sys.service.impl.FlowButtonServiceImpl;
import com.scs.application.modules.sys.service.impl.FlowNodeServiceImpl;
import com.scs.application.modules.sys.service.impl.FlowServiceImpl;
import com.scs.application.modules.sys.service.impl.TableDataViewServiceImpl;
import com.scs.application.modules.sys.vo.TableColumn;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Slf4j
public class DataViewController {

    @Autowired
    private DataViewMapper dataViewMapper;

    @Autowired
    private FlowServiceImpl flowService;

    @Autowired
    private FlowNodeServiceImpl flowNodeService;

    @Autowired
    private FlowButtonServiceImpl flowButtonService;

    @Autowired
    private ProgramService programService;

    @Autowired
    private DataViewAdapter dataViewAdapter;
    @Qualifier("tableDataViewServiceImpl")
    @Autowired
    private DataViewService tableDataViewServiceImpl;
    @Autowired
    private TableDataViewServiceImpl tableDataViewServiceImpl2;

    @Autowired
    private SystemProperties systemProperties;

    @GetMapping(value = "/data-view/find")
    public RestResult getDataView(
            @RequestParam("viewKey") String viewKey,
            @RequestParam(name = "flowKey", defaultValue = "") String flowKey) {
        HashMap<String, Object> result = getView(viewKey, flowKey);
        if (result == null) {
            return RestResult.error("获取视图失败！");
        }
        return RestResult.ok("获取视图成功！", result);
    }
    @GetMapping(value = "/data-view/findCache")
    public RestResult findCache(
            @RequestParam("viewKey") String viewKey) {
        String dataViewString = CacheUtils.get(CacheUtils.DATAVIEW_CACHE, viewKey) + "";
        if (dataViewString.length() < 1) {
            return null;
        }
        JSONObject jsonDataView = JSONObject.parseObject(dataViewString);
        return RestResult.ok("获取视图成功！", jsonDataView);
    }

    @RequestMapping(value = "/program/dict/list", method = RequestMethod.GET)
    public RestResult getDictList(StringReceive stringReceive) {
        HashMap<String, Object> result = new HashMap<String, Object>();
        String dictString = stringReceive.getContents();
        JSONObject dictObj = JSON.parseObject(dictString);
        for (String key : dictObj.keySet()) {
            result.put(key, dataViewMapper.select(dictObj.getString(key)));
        }
        return RestResult.ok("获取字典成功！", result);
    }

    @RequestMapping(value = "/program/data-view/list", method = RequestMethod.GET)
    public RestResult getDataViewList() {
        List<DataViewDTO> dataviews = dataViewAdapter.getDataViewService().getDataViewList();
        return RestResult.ok("获取视图成功！", dataviews);
    }

    @RequestMapping(value = "/program/data-view/delete", method = RequestMethod.DELETE)
    public RestResult deleteDataView(@RequestBody Map<String, Object> para) {
        List<Serializable> ids = (List<Serializable>) para.get("ids");
        String viewKey = ids.get(0).toString();
        Boolean isOk = dataViewAdapter.getDataViewService().deleteView(viewKey);
        return isOk ? RestResult.ok("删除视图成功！") : RestResult.error("删除视图失败！");
    }

    @RequestMapping(value = "/program/create-crud", method = RequestMethod.POST)
    public RestResult createCRUD(@RequestBody CreateCRUDFileDTO createCRUDFileDTO) {
        programService.createCRUD(createCRUDFileDTO);
        return RestResult.ok("生成文件完成！");
    }

    @RequestMapping(value = "/program/create-all", method = RequestMethod.POST)
    public RestResult createAll(@RequestBody CreateCRUDFileDTO createCRUDFileDTO) {
        programService.createAll(createCRUDFileDTO);
        return RestResult.ok("生成文件完成！");
    }

    @RequestMapping(value = "/program/create-front", method = RequestMethod.POST)
    public RestResult createFront(@RequestBody CreateFrontFileDTO createFrontFileDTO) {
        programService.createFront(createFrontFileDTO);
        return RestResult.ok("生成前台文件完成！");
    }

    @RequestMapping(value = "/program/table-columns", method = RequestMethod.GET)
    public RestResult tableSchema(@RequestParam String tableName) {
        List<TableColumn> models = dataViewMapper.getTableColumns(tableName);
        return RestResult.ok("获取表格列信息成功！", models);
    }

    @RequestMapping(value = "/program/data-view/save", method = RequestMethod.POST)
    public RestResult saveDataView(@RequestBody JSONObject dataViewJson) {
        return RestResult.ok("保存视图成功！", tableDataViewServiceImpl2.saveView(dataViewJson));
    }

    @RequestMapping(value = "/program/data-view/listWithSvnLock", method = RequestMethod.GET)
    public RestResult listWithSvnLock() {
        return RestResult.ok(dataViewAdapter.getDataViewService().listWithSvnLock());
    }

    @RequestMapping(value = "/program/data-view/listObjs", method = RequestMethod.GET)
    public RestResult listObjs() {
        List<String> viewKeyList = tableDataViewServiceImpl2.list(Wrappers.<DataView>query().select("view_key")).stream().map(DataView::getViewKey).collect(Collectors.toList());
        HashMap<String, Object> viewMap = new HashMap<String, Object>();
        if (viewKeyList != null && viewKeyList.size() > 0) {
            for (String viewKey : viewKeyList) {
                try {
                    viewMap.put(viewKey, JSONObject.parseObject(CacheUtils.get(CacheUtils.DATAVIEW_CACHE, viewKey) + ""));
                } catch (Exception ex) {
                    log.error(ex.getMessage());
                }
            }
        }
        return RestResult.ok("获取成功！", viewMap);
    }

    /**
     * 根据视图Key和流程Key获取相关视图和流程信息
     *
     * @param viewKey
     * @param flowKey
     * @return
     */
    private HashMap<String, Object> getView(String viewKey, String flowKey) {
        HashMap<String, Object> result = new HashMap<>();

        String dataViewString = CacheUtils.get(CacheUtils.DATAVIEW_CACHE, viewKey) + "";
        if (dataViewString.length() < 1) {
            return null;
        }
        JSONObject jsonDataView = JSONObject.parseObject(dataViewString);
        result.put("view", jsonDataView);
        if (StringUtils.isNotBlank(flowKey)) {
            Flow flow = flowService.findByFlowKey(flowKey);
            result.put("flow", flow);
            if (flow != null) {
                result.put("flowNodes",
                        flowNodeService.getByFlowId(flow.getId()));
                result.put("flowButtons",
                        flowButtonService.getByFlowId(flow.getId()));
            }
        }
        return result;
    }

    /**
     * 根据视图Key获取产品和项目视图
     *
     * @param viewKey
     * @return
     */
    @RequestMapping(value = "/program/data-view/diff", method = RequestMethod.GET)
    public RestResult getTwoDataViews(@RequestParam String viewKey) {
        DataViewService productDvService = dataViewAdapter.getDataViewService(false);
        if (productDvService.getClass().getName().equals(dataViewAdapter.getDataViewService().getClass().getName())) {
            throw new BusinessException("产品分支不支持该功能");
        }
        HashMap<String, Object> result = new HashMap<>();
        String dataViewString = CacheUtils.get(CacheUtils.DATAVIEW_CACHE, viewKey) + "";
        result.put("txtProjectDataView", dataViewString);

        String productDvString = productDvService.getView(viewKey);
        result.put("txtProductDataView", productDvString);
        return RestResult.ok("获取数据成功", result);
    }

    /**
     * 同步产品视图 所有
     *
     * @return
     */
    @GetMapping(value = "/program/data-view/syncDataViewsAll")
    public RestResult syncDataViewsAll() {
        return RestResult.ok(tableDataViewServiceImpl.syncDataViewsAll());
    }

    /**
     * 选择 获取数据列表
     */
    @GetMapping("/program/data-view/page")
    public PageResult pageForSelect() {
        QueryContext queryContext = QueryContextHolder.currentContext();
        queryContext.getWrapper().select("id,view_key,view_name,module_name,description,view_type,modifier,gmt_modified");
        IPage pageResult = tableDataViewServiceImpl2.page(queryContext);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }
}
